import blue
import uix
import uiutil
import xtriui
import sys
import form
import util
import menu
import service
import benchmark1
import os
import trinity
import types
import uicls
import geo2
import world
import cameras
BUTTONSPACING = 66
WINDOWHEIGHT = 45
WINDOWWIDTH = 110
FILE_BUNKERS = 'Bunkers.txt'
FILE_ENTITIES = 'Entities.txt'
FILE_GATES = 'GateTest.txt'
FILE_STELLAR = 'StellarReport.txt'
FILE_BELTS = 'BeltTest.txt'
FILE_FWREPORT = 'FacWarReport.txt'
Progress = lambda title, text, current, total: sm.GetService('loading').ProgressWnd(title, text, current, total)

class InsiderWnd(uicls.Window):
    __guid__ = 'form.InsiderWnd'
    default_top = 0
    default_left = '__center__'
    default_fixedHeight = WINDOWHEIGHT

    def ApplyAttributes(self, attributes):
        uicls.Window.ApplyAttributes(self, attributes)
        self.SetMinSize([WINDOWWIDTH, WINDOWHEIGHT])
        self.SetHeight(WINDOWHEIGHT)
        self.MakeUnResizeable()
        self.HideClippedIcon()
        self.HideMainIcon()
        self.SetTopparentHeight(0)
        self.SetCaption('Insider')



    def OnClose_(self, *args):
        settings.public.ui.Set('Insider', False)



    def OnResizeUpdate(self, *args):
        child = uiutil.FindChild(self, 'btns')
        if (child is not None):
            self.width = (len(child.children) * BUTTONSPACING)




class InsiderService(service.Service):
    __module__ = __name__
    __doc__ = 'Insider v2.0'
    __exportedcalls__ = {'Show': [],
     'WarpTo': [service.ROLE_IGB],
     'TravelTo': [service.ROLE_IGB]}
    __guid__ = 'svc.insider'
    __servicename__ = 'insider'
    __displayname__ = 'Insider Service'
    __notifyevents__ = ['OnSessionChanged']

    def HealRemoveAllContainers(self):
        containers = [const.groupAuditLogSecureContainer,
         const.groupCargoContainer,
         const.groupFreightContainer,
         const.groupSecureCargoContainer,
         const.groupWreck]
        for entry in containers:
            self.HealRemove(entry)




    def HealRemove(self, type, group = True):
        targets = []
        bp = sm.GetService('michelle').GetBallpark()
        if bp:
            if group:
                for ballID in bp.balls.keys():
                    item = bp.GetInvItem(ballID)
                    if (item and (item.groupID == type)):
                        targets.append(item.itemID)

            else:
                for ballID in bp.balls.keys():
                    item = bp.GetInvItem(ballID)
                    if (item and (item.categoryID == type)):
                        if (type == const.categoryStructure):
                            if (sm.GetService('pwn').GetStructureState(item)[0] == 'unanchored'):
                                targets.append(item.itemID)
                        elif (type == const.categoryShip):
                            if not bp.GetBall(ballID).isInteractive:
                                targets.append(item.itemID)
                        else:
                            targets.append(item.itemID)

            for itemID in targets:
                sm.GetService('slash').SlashCmd(('heal %d 0' % itemID))

            blue.pyos.synchro.Sleep(250)



    def SlashBtnClick(self, cmd):
        return lambda : sm.GetService('slash').SlashCmd(cmd)



    def GetInsiderDir(self, *args):
        path = os.path.normpath(blue.win32.SHGetFolderPath(blue.win32.CSIDL_PERSONAL))
        path = os.path.join(path, 'EVE\\insider')
        return path



    def GetBenchmarkDir(self, *args):
        path = os.path.normpath(blue.win32.SHGetFolderPath(blue.win32.CSIDL_PERSONAL))
        path = os.path.join(path, 'EVE\\logs\\Benchmarks')
        return path



    def GetTimestamp(self, *args):
        invalidChars = '\\/:*?"<>| '
        timestamp = util.FmtDate(blue.os.GetTime())
        for char in invalidChars:
            timestamp = timestamp.replace(char, '.')

        return timestamp



    def WaitOutSession(self, *args):
        if (blue.os.GetTime() <= session.nextSessionChange):
            ms = (1000 + ((1000L * (session.nextSessionChange - blue.os.GetTime())) / 10000000L))
            blue.pyos.synchro.Sleep(ms)



    def MakeMenu(self, list, anchor):
        mv = menu.CreateMenuView(menu.CreateMenuFromList(list), None, None)
        anchorwindow = sm.GetService('window').GetWindow('insider')
        x = max(uiutil.GetChild(anchorwindow, anchor).GetAbsolute()[0], 0)
        y = (anchorwindow.top + anchorwindow.height)
        if (((anchorwindow.top + anchorwindow.height) + mv.height) > eve.triapp.uilib.desktop.height):
            mv.top = min((sm.GetService('window').GetWindow('insider').top - mv.height), y)
        else:
            mv.top = min((eve.triapp.uilib.desktop.width - mv.height), y)
        mv.left = min((eve.triapp.uilib.desktop.width - mv.width), x)
        uicls.Frame(parent=mv, color=(1.0, 1.0, 1.0, 0.2))
        uicore.layer.menu.children.insert(0, mv)



    def TravelTo(self, destination, *args):
        try:
            sm.GetService('slash').SlashCmd(('/tr me %s' % destination))
        except UserError, e:
            if (e.msg == 'SystemCheck_TransferFailed_Loading'):
                eve.Message('CustomNotify', {'notify': 'Spooling up system. Please wait.'})
                blue.pyos.synchro.Sleep(10000)
                sm.GetService('slash').SlashCmd(('/tr me %s' % destination))
            sys.exc_clear()



    def TravelToLocation(self, destination, *args):
        if util.IsSolarSystem(destination):
            currentSys = session.solarsystemid2
            while (currentSys != destination):
                self.TravelTo(destination)
                currentSys = session.solarsystemid2

        else:
            try:
                self.TravelTo(destination)
            except UserError, e:
                eve.Message('CustomNotify', {'notify': 'Spooling up system. Please wait.'})
                blue.pyos.synchro.Sleep(10000)
                self.TravelTo(destination)
            sys.exc_clear()



    def RegionBunkerTest(self, positive = True, faction = 'All', *args):
        amarr = [10000036, 10000038]
        caldari = [10000033, 10000069]
        gallente = [10000064,
         10000068,
         10000048]
        minmatar = [10000030, 10000042]
        all = (((amarr + caldari) + gallente) + minmatar)
        lookUp = {'amarr': amarr,
         'caldari': caldari,
         'gallente': gallente,
         'minmatar': minmatar,
         'all': all}

        def Populate(regionID):
            constellations = []
            systems = []
            constellations = sm.GetService('map').GetChildren(regionID)
            for sys in constellations:
                systems += sm.GetService('map').GetChildren(sys)

            return systems


        allSystems = []
        systemsInFacWar = []
        systemsNotInFacWar = []
        if faction:
            regions = lookUp[faction.lower()]
            for region in regions:
                allSystems += Populate(region)

            for system in allSystems:
                if sm.RemoteSvc('facWarMgr').GetFacWarSystems().has_key(system):
                    systemsInFacWar.append(system)
                else:
                    systemsNotInFacWar.append(system)

            if positive:
                testSystems = systemsInFacWar
                testType = 'Positive'
            else:
                testSystems = systemsNotInFacWar
                testType = 'Negative'
            testLength = len(testSystems)
            testMinutes = (testLength / 2)
            if (eve.Message('CustomQuestion', {'header': 'Search for bunkers?',
             'question': ('Do you really want to search the region for bunkers? It is %d systems, and will take approximately %d minutes to run.' % (testLength, testMinutes))}, uix.YESNO) == uix.ID_YES):
                filename = ('%s.%s.%s.%s' % (self.GetTimestamp(),
                 faction,
                 testType,
                 FILE_BUNKERS))
                TARGET = os.path.join(self.GetInsiderDir(), filename)
                f = blue.os.CreateInstance('blue.ResFile')
                if not f.Open(TARGET, 0):
                    f.Create(TARGET)
                f.Write('Bunker typeID\tBunker Name\tBunker itemID\tSystem Occupier\tSystem Sovereignty\tSystem Name\tSystem ID\tConstellation Name\tConstellation ID\tRegion Name\tRegion ID')
                f.Write('\r\n')
                for system in testSystems:
                    self.WaitOutSession()
                    self.TravelToLocation(system)
                    bunkers = []
                    blue.pyos.synchro.Sleep(5000)
                    bp = sm.GetService('michelle').GetBallpark()
                    if bp:
                        for ballID in bp.balls.keys():
                            item = bp.GetInvItem(ballID)
                            if (item and (item.groupID in (const.groupControlBunker))):
                                bunkers.append(item)

                    systemName = cfg.evelocations.Get(system).name
                    constellation = cfg.evelocations.Get(session.constellationid).name
                    region = cfg.evelocations.Get(session.regionid).name
                    systemSov = cfg.eveowners.Get(sm.RemoteSvc('stationSvc').GetSolarSystem(system).factionID).name
                    if bunkers:
                        for bunker in bunkers:
                            bunkertypeID = bunker.typeID
                            bunkerName = cfg.invtypes.Get(bunkertypeID).name
                            bunkeritemID = bunker.itemID
                            facwarsys = sm.GetService('facwar').GetFacWarSystem(system)
                            systemOccupier = cfg.eveowners.Get(facwarsys.get('occupierID')).name
                            f.Write(('%s' % bunkertypeID))
                            f.Write(('\t%s' % bunkerName.encode('utf8')))
                            f.Write(('\t%s' % bunkeritemID))
                            f.Write(('\t%s' % systemOccupier.encode('utf8')))
                            f.Write(('\t%s' % systemSov.encode('utf8')))
                            f.Write(('\t%s' % systemName.encode('utf8')))
                            f.Write(('\t%s' % system))
                            f.Write(('\t%s' % constellation.encode('utf8')))
                            f.Write(('\t%s' % session.constellationid))
                            f.Write(('\t%s' % region.encode('utf8')))
                            f.Write(('\t%s' % session.regionid))
                            f.Write('\r\n')

                    else:
                        bunkertypeID = '-'
                        bunkerName = '-'
                        bunkeritemID = '-'
                        systemOccupier = '-'
                        f.Write(('%s' % bunkertypeID))
                        f.Write(('\t%s' % bunkerName.encode('utf8')))
                        f.Write(('\t%s' % bunkeritemID))
                        f.Write(('\t%s' % systemOccupier.encode('utf8')))
                        f.Write(('\t%s' % systemSov.encode('utf8')))
                        f.Write(('\t%s' % systemName.encode('utf8')))
                        f.Write(('\t%s' % system))
                        f.Write(('\t%s' % constellation.encode('utf8')))
                        f.Write(('\t%s' % session.constellationid))
                        f.Write(('\t%s' % region.encode('utf8')))
                        f.Write(('\t%s' % session.regionid))
                        f.Write('\r\n')

        try:
            f.Close()
        except:
            sys.exc_clear()



    def EntitySpawn(self, label = None, chosenGroup = None, *args):
        entityDict = {}
        lootEntities = []
        respawnEntities = []
        if label:
            label = label.replace(' ', '_')
            label = label.replace("'", '')
        if (chosenGroup.__class__ != list):
            chosenGroup = [chosenGroup]
        for group in chosenGroup:
            if (cfg.invgroups.Get(group).categoryID in (const.categoryEntity)):
                entityDict[group] = []

        for type in cfg.invtypes:
            if (type.groupID in entityDict):
                entityDict[type.groupID].append(type.typeID)

        for values in entityDict.itervalues():
            for typeID in values:
                name = cfg.invtypes.Get(typeID).name
                if name.lower().__contains__('test'):
                    continue
                lootEntities.append(typeID)
                continue


        if (eve.Message('CustomQuestion', {'header': 'Spawn NPCs?',
         'question': ("Do you really want to spawn all those NPCs? It's quite alot (%d entities in %d groups)" % (len(lootEntities), len(entityDict)))}, uix.YESNO) == uix.ID_YES):
            filename = ('%s.%s.%s' % (self.GetTimestamp(),
             label,
             FILE_ENTITIES))
            TARGET = os.path.join(self.GetInsiderDir(), filename)
            f = blue.os.CreateInstance('blue.ResFile')
            if not f.Open(TARGET, 0):
                f.Create(TARGET)
            f.Write('Status\tLoot\tEmpty\tTypeID\tEntity Type\tWreck Type\tEntity Name\tWreck Name\tWreck State')
            f.Write('\r\n')
            for entity in lootEntities:
                dudSpawn = False
                if cfg.invgroups.Get(cfg.invtypes.Get(entity).groupID).anchored:
                    respawnEntities.append(entity)
                    print ('appended entity %s' % entity)
                    continue
                else:
                    blue.pyos.synchro.Sleep(1000)
                    sm.GetService('slash').SlashCmd(('/entity deploy 10 %d' % entity))
                blue.pyos.synchro.Sleep(1000)
                sm.GetService('slash').SlashCmd('/nuke')
                blue.pyos.synchro.Sleep(2000)
                wrecks = []
                count = 1000
                while ((not wrecks) and count):
                    count -= 1
                    bp = sm.GetService('michelle').GetBallpark()
                    for ballID in bp.balls.keys():
                        item = bp.GetInvItem(ballID)
                        if (item and (item.groupID in (const.groupWreck, const.groupCargoContainer))):
                            wrecks.append(item.itemID)


                if not wrecks:
                    blue.pyos.synchro.Sleep(5000)
                    bp = sm.GetService('michelle').GetBallpark()
                    for ballID in bp.balls.keys():
                        item = bp.GetInvItem(ballID)
                        if (item and (item.groupID in (const.groupWreck, const.groupCargoContainer))):
                            wrecks.append(item.itemID)

                if not wrecks:
                    dudSpawn = True
                emptyWreck = int()
                okWreck = int()
                entityType = cfg.invgroups.Get(cfg.invtypes.Get(entity).groupID).name
                entityName = cfg.invtypes.Get(entity).name
                idealWreckName = ('%s Wreck' % entityName)
                if not dudSpawn:
                    actualWreckName = 'None'
                    for wreckID in wrecks:
                        empty = sm.GetService('state').CheckWreckEmpty(bp.GetInvItem(wreckID))
                        if empty:
                            emptyWreck += 1
                        else:
                            okWreck += 1
                        actualWreckName = cfg.evelocations.Get(wreckID).name
                        wreckType = cfg.invtypes.Get(sm.GetService('michelle').GetBallpark().GetInvItem(wreckID).typeID).name

                    wreckNameState = 'Error'
                    if (idealWreckName == actualWreckName):
                        wreckNameState = 'OK'
                    try:
                        if (okWreck > emptyWreck):
                            f.Write('OK')
                            f.Write(('\t%s' % okWreck))
                            f.Write(('\t%s' % emptyWreck))
                            f.Write(('\t%s' % entity))
                            f.Write(('\t%s' % entityType.encode('utf8')))
                            f.Write(('\t%s' % wreckType.encode('utf8')))
                            f.Write(('\t%s' % entityName.encode('utf8')))
                            f.Write(('\t%s' % actualWreckName.encode('utf8')))
                            f.Write(('\t%s' % wreckNameState))
                            f.Write('\r\n')
                        elif not okWreck:
                            f.Write('Critical')
                            f.Write(('\t-\t-\t%s' % entity))
                            f.Write(('\t%s' % entityType.encode('utf8')))
                            f.Write(('\t%s' % wreckType.encode('utf8')))
                            f.Write(('\t%s' % entityName.encode('utf8')))
                            f.Write(('\t%s' % actualWreckName.encode('utf8')))
                            f.Write(('\t%s' % wreckNameState))
                            f.Write('\r\n')
                        else:
                            f.Write('Warning')
                            f.Write(('\t%s' % okWreck))
                            f.Write(('\t%s' % emptyWreck))
                            f.Write(('\t%s' % entity))
                            f.Write(('\t%s' % entityType.encode('utf8')))
                            f.Write(('\t%s' % wreckType.encode('utf8')))
                            f.Write(('\t%s' % entityName.encode('utf8')))
                            f.Write(('\t%s' % actualWreckName.encode('utf8')))
                            f.Write(('\t%s' % wreckNameState))
                            f.Write('\r\n')
                    except:
                        sys.exc_clear()
                        f.Write('\r\n')
                        f.Write('Fail')
                        f.Write(('\t-\t-\t%s' % entity))
                        f.Write(('\t%s' % entityType.encode('utf8')))
                        f.Write(('\t%s' % entityName.encode('utf8')))
                        f.Write('\r\n')
                else:
                    f.Write('Null')
                    f.Write(('\t-\t-\t%s' % entity))
                    f.Write(('\t%s' % entityType.encode('utf8')))
                    f.Write(('\t%s' % entityName.encode('utf8')))
                    f.Write('\tNone\tNone\tNone')
                    f.Write('\r\n')
                self.HealRemove(const.groupWreck)
                self.HealRemove(const.groupCargoContainer)

            if respawnEntities:
                f.Write('\r\n')
                f.Write('The following entities respawn over time and were not tested:')
                f.Write('\r\n')
                for entity in respawnEntities:
                    entityType = cfg.invgroups.Get(cfg.invtypes.Get(entity).groupID).name
                    entityName = cfg.invtypes.Get(entity).name
                    f.Write('Unspawned')
                    f.Write(('\t\t\t%s' % entity))
                    f.Write(('\t%s' % entityType.encode('utf8')))
                    f.Write(('\t%s' % entityName.encode('utf8')))
                    f.Write('\r\n')

        try:
            f.Close()
        except:
            sys.exc_clear()



    def RegionGateTest(self, constellation = None, *args):

        def Populate(areaOfInterest):
            data = {}
            systems = []
            mapSvc = sm.GetService('map')
            systemmapSvc = sm.GetService('systemmap')
            if (areaOfInterest.__class__ != list):
                areaOfInterest = [areaOfInterest]
            for constellation in areaOfInterest:
                systems += mapSvc.GetChildren(constellation)

            for system in systems:
                title = 'Examining Systems...'
                systemName = cfg.evelocations.Get(system).name
                constellationID = cfg.evelocations.Get(mapSvc.GetParent(system))
                constellationName = cfg.evelocations.Get(constellationID).name
                regionID = cfg.evelocations.Get(mapSvc.GetParent(constellationID.id))
                regionName = cfg.evelocations.Get(regionID).name
                text = ('%s, %s, %s' % (systemName,
                 constellationName,
                 regionName))
                Progress(title, text, systems.index(system), len(systems))
                systemItems = systemmapSvc.GetSolarsystemData(system)
                systemItems = systemItems.Index('itemID')
                stargates = {}
                for object in systemItems:
                    item = systemItems[object]
                    if (cfg.invtypes.Get(item.typeID).groupID in (const.groupStargate)):
                        stargates[item.itemName] = {'gateID': item.itemID,
                         'destGateID': item.destinations[0]}

                data[system] = stargates

            Progress('Mapping Complete!', 'Done!', 1, 1)
            return data



        def Wait(count, *args):
            blue.pyos.synchro.Sleep((count * 1000))


        sysCount = int()
        jumpCount = int()
        regionData = Populate(constellation)
        for (k, v,) in regionData.iteritems():
            sysCount += 1
            jumpCount += len(v)

        approxDuration = (jumpCount * 0.5)
        if (eve.Message('CustomQuestion', {'header': 'Travel the universe?',
         'question': ('Do you really want to visit all the gates in this region? It will take approximately %d minutes.' % approxDuration)}, uix.YESNO) == uix.ID_YES):
            filename = ('%s.%s.%s' % (self.GetTimestamp(),
             cfg.evelocations.Get(session.regionid).name,
             FILE_GATES))
            f = blue.os.CreateInstance('blue.ResFile')
            TARGET = os.path.join(self.GetInsiderDir(), filename)
            if not f.Open(TARGET, 0):
                f.Create(TARGET)
            gok = int()
            gfail = int()
            sok = int()
            sfail = int()
            stargates = []
            self.WaitOutSession()
            for (system, gates,) in regionData.iteritems():
                f.Write(('%s' % cfg.evelocations.Get(system).name.encode('utf8')))
                f.Write('\r\n')
                for (name, info,) in gates.iteritems():
                    sysdest = name.split('(')[1].split(')')[0]
                    f.Write(('-> %s' % sysdest.encode('utf8')))
                    f.Write('\r\n')
                    sysdestID = sm.RemoteSvc('lookupSvc').LookupLocationsByGroup(const.groupSolarSystem, sysdest)
                    for each in sysdestID:
                        sysdestID = each.itemID

                    Wait(5)
                    self.TravelToLocation(system)
                    Wait(5)
                    bp = sm.GetService('michelle').GetBallpark()
                    for ballID in bp.balls.keys():
                        item = bp.GetInvItem(ballID)
                        if (item and (item.groupID in (const.groupStargate))):
                            stargates.append(item.itemID)

                    if (info['gateID'] in stargates):
                        self.TravelToLocation(info['gateID'])
                        self.WaitOutSession()
                        Wait(5)
                        try:
                            sm.GetService('sessionMgr').PerformSessionChange('autopilot', sm.GetService('michelle').GetRemotePark().StargateJump, info['gateID'], info['destGateID'], session.shipid)
                            Wait(10)
                        except:
                            sys.exc_clear()
                            f.Write('\t\tERROR: Jump failed')
                            f.Write('\r\n')
                    stargates = []
                    bp = sm.GetService('michelle').GetBallpark()
                    for ballID in bp.balls.keys():
                        item = bp.GetInvItem(ballID)
                        if (item and (item.groupID in (const.groupStargate))):
                            data = sm.GetService('tactical').GetEntryData(item, bp.GetBall(item.itemID))
                            distance = data.ball().surfaceDist
                            stargates.append(item.itemID)

                    if (info['destGateID'] in stargates):
                        item = bp.GetInvItem(info['destGateID'])
                        distance = sm.GetService('tactical').GetEntryData(item, bp.GetBall(item.itemID)).ball().surfaceDist
                        if (distance < 50000):
                            gok += 1
                            f.Write('\t\tGate: OK')
                            f.Write('\r\n')
                        else:
                            f.Write('\t\tGate: There, but distant')
                            f.Write('\r\n')
                    else:
                        gfail += 1
                        f.Write('\t\tGate: FAIL')
                        f.Write('\r\n')
                    if (cfg.evelocations.Get(session.locationid).name == sysdest):
                        sok += 1
                        f.Write('\t\tSystem: OK')
                        f.Write('\r\n')
                    else:
                        sfail += 1
                        f.Write('\t\tSystem: FAIL')
                        f.Write('\r\n')
                    self.WaitOutSession()

                f.Write('-----------------')
                f.Write('\r\n')

            f.Write('Gates:')
            f.Write('\r\n')
            f.Write(('\tOK: %s' % gok))
            f.Write('\r\n')
            f.Write(('\tFAIL: %s' % gfail))
            f.Write('\r\n')
            f.Write('Systems:')
            f.Write('\r\n')
            f.Write(('\tOK: %s' % sok))
            f.Write('\r\n')
            f.Write(('\tFAIL: %s' % sfail))
            f.Write('\r\n')
            f.Close()



    def FacWarStatus(self, *args):
        facWar = sm.RemoteSvc('facWarMgr')
        map = sm.GetService('map')
        systems = facWar.GetFacWarSystems()
        f = blue.os.CreateInstance('blue.ResFile')
        filename = ('%s.%s' % (self.GetTimestamp(), FILE_FWREPORT))
        TARGET = os.path.join(self.GetInsiderDir(), filename)
        if not f.Open(TARGET, 0):
            f.Create(TARGET)
        f.Write('System ID\tSystem Name\tConstellation ID\tConstellation Name\tRegion ID\tRegion Name\tOccupier\tSovereignty\tConquered')
        f.Write('\r\n')
        for (k, v,) in systems.iteritems():
            systemID = k
            systemName = cfg.evelocations.Get(systemID).name
            constellationID = map.GetParent(systemID)
            constellationName = cfg.evelocations.Get(constellationID).name
            regionID = map.GetParent(constellationID)
            regionName = cfg.evelocations.Get(regionID).name
            occupierName = cfg.eveowners.Get(v['occupierID']).name
            factionName = cfg.eveowners.Get(v['factionID']).name
            state = (occupierName == factionName)
            f.Write(('%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s' % (systemID,
             systemName,
             constellationID,
             constellationName,
             regionID,
             regionName,
             occupierName,
             factionName,
             (not state))))
            f.Write('\r\n')

        try:
            f.Close()
        except:
            sys.exc_clear()



    def StoreRegionData(self, *args):
        constellations = []
        systems = []
        constellations = sm.GetService('map').GetChildren(session.regionid)
        for sys in constellations:
            systems += sm.GetService('map').GetChildren(sys)

        regionName = cfg.evelocations.Get(session.regionid).name
        filename = ('%s.%s.%s' % (self.GetTimestamp(),
         regionName,
         FILE_STELLAR))
        f = blue.os.CreateInstance('blue.ResFile')
        TARGET = os.path.join(self.GetInsiderDir(), filename)
        if not f.Open(TARGET, 0):
            f.Create(TARGET)
        f.Write('Object itemID\tObject typeID\tObject Type\tName\tLocation ID\tDestination\tx\ty\tz\tObject orbitID')
        f.Write('\r\n')
        for system in systems:
            title = 'Examining Systems...'
            systemName = cfg.evelocations.Get(system).name
            constellationID = cfg.evelocations.Get(sm.GetService('map').GetParent(system))
            constellationName = cfg.evelocations.Get(constellationID).name
            text = ('%s, %s' % (systemName, constellationName))
            Progress(title, text, systems.index(system), len(systems))
            systemItems = sm.GetService('systemmap').GetSolarsystemData(system)
            for object in systemItems:
                f.Write(('%s' % object.itemID))
                f.Write(('\t%s' % object.typeID))
                f.Write(('\t%s' % cfg.invtypes.Get(object.typeID).name.encode('utf8')))
                f.Write(('\t%s' % object.itemName.encode('utf8')))
                f.Write(('\t%s' % object.locationID))
                f.Write(('\t%s' % object.destinations.__str__()))
                f.Write(('\t%g' % object.x))
                f.Write(('\t%g' % object.y))
                f.Write(('\t%g' % object.z))
                f.Write(('\t%s' % object.orbitID))
                f.Write('\r\n')


        try:
            f.Close()
        except:
            sys.exc_clear()
        Progress('Mapping Complete!', 'Done!', 1, 1)



    def RegionBeltTest(self, constellation = None, *args):

        def Populate(areaOfInterest):
            systems = []
            belts = []
            if (areaOfInterest.__class__ != list):
                areaOfInterest = [areaOfInterest]
            for constellation in areaOfInterest:
                systems += sm.GetService('map').GetChildren(constellation)

            for system in systems:
                title = 'Examining Systems...'
                systemName = cfg.evelocations.Get(system).name
                constellationID = cfg.evelocations.Get(sm.GetService('map').GetParent(system))
                constellationName = cfg.evelocations.Get(constellationID).name
                regionID = cfg.evelocations.Get(sm.GetService('map').GetParent(constellationID.id))
                regionName = cfg.evelocations.Get(regionID).name
                text = ('%s, %s, %s' % (systemName,
                 constellationName,
                 regionName))
                Progress(title, text, systems.index(system), len(systems))
                systemItems = sm.GetService('systemmap').GetSolarsystemData(system)
                systemItems = systemItems.Index('itemID')
                for object in systemItems:
                    item = systemItems[object]
                    if (cfg.invtypes.Get(item.typeID).groupID in (const.groupAsteroidBelt)):
                        belts.append(item.itemID)


            Progress('Mapping Complete!', 'Done!', 1, 1)
            return (belts, systems)



        def Wait(count, *args):
            blue.pyos.synchro.Sleep((count * 1000))


        if not constellation:
            return 
        (regionBeltData, regionSystemData,) = Populate(constellation)
        sysCount = len(regionSystemData)
        approxDuration = (sysCount * 0.5)
        if (eve.Message('CustomQuestion', {'header': 'Travel the universe?',
         'question': ('Do you really want to visit all the belts in this region? It will take approximately %d minutes.' % approxDuration)}, uix.YESNO) == uix.ID_YES):
            filename = ('%s.%s.%s' % (self.GetTimestamp(),
             cfg.evelocations.Get(session.regionid).name,
             FILE_BELTS))
            f = blue.os.CreateInstance('blue.ResFile')
            TARGET = os.path.join(self.GetInsiderDir(), filename)
            if not f.Open(TARGET, 0):
                f.Create(TARGET)
            asteroidGroups = []
            for asteroid in cfg.invgroups:
                if (asteroid.categoryID in (const.categoryAsteroid)):
                    asteroidGroups.append(asteroid.id)

            f.Write('Solarsystem itemID\tSolarsystem Name\tBelt itemID\tBelt Name\tAsteroid Types Present')
            f.Write('\r\n')
            for belt in regionBeltData:
                survey = []
                try:
                    self.TravelToLocation(belt)
                except:
                    sys.exc_clear()
                    self.WaitOutSession()
                    self.TravelToLocation(belt)
                Wait(5)
                bp = sm.GetService('michelle').GetBallpark()
                gotBelt = False
                bpCount = int()
                while not gotBelt:
                    for ballID in bp.balls.keys():
                        item = bp.GetInvItem(ballID)
                        if (item and (item.itemID == belt)):
                            gotBelt = True
                            break

                    bpCount += 1
                    if (bpCount > 10):
                        break
                    Wait(5)
                    bp = sm.GetService('michelle').GetBallpark()

                if gotBelt:
                    for ballID in bp.balls.keys():
                        item = bp.GetInvItem(ballID)
                        if (item and (item.groupID in asteroidGroups)):
                            if survey.__contains__(item.typeID):
                                pass
                            else:
                                survey.append(item.typeID)

                    if not survey:
                        Wait(5)
                        bp = sm.GetService('michelle').GetBallpark()
                        for ballID in bp.balls.keys():
                            item = bp.GetInvItem(ballID)
                            if (item and (item.groupID in asteroidGroups)):
                                if survey.__contains__(item.typeID):
                                    pass
                                else:
                                    survey.append(item.typeID)

                    survey.sort()
                    f.Write(('%s' % session.locationid))
                    f.Write(('\t%s' % cfg.evelocations.Get(session.solarsystemid2).name.encode('utf8')))
                    f.Write(('\t%s' % belt))
                    f.Write(('\t%s' % cfg.evelocations.Get(belt).name.encode('utf8')))
                    f.Write('\t')
                    for asteroid in survey:
                        f.Write(('%s, ' % cfg.invtypes.Get(asteroid).name.encode('utf8')))

                    f.Write('\r\n')

            try:
                f.Close()
            except:
                sys.exc_clear()



    def Automated(self, *args):
        fw = []
        allIDs = []
        usedIDs = []
        spawnMenu = []
        entitySpawnGroups = ['Asteroid Angel Cartel',
         'Asteroid Blood Raiders',
         'Asteroid Guristas',
         'Asteroid Rogue Drone',
         "Asteroid Sansha's Nation",
         'Asteroid Serpentis',
         'Deadspace Angel Cartel',
         'Deadspace Blood Raiders',
         'Deadspace Guristas',
         'Deadspace Overseer',
         'Deadspace Rogue Drone',
         "Deadspace Sansha's Nation",
         'Deadspace Serpentis',
         'Mission Amarr Empire',
         'Mission CONCORD',
         'Mission Caldari State',
         'Mission Drone',
         'Mission Gallente Federation',
         'Mission Generic',
         'Mission Khanid',
         'Mission Minmatar Republic',
         'Mission Mordu',
         'Mission Thukker',
         'Storyline',
         'Other']
        noLootEntities = [const.groupConcordDrone,
         const.groupFactionDrone,
         const.groupPoliceDrone]
        dontSpawn = [const.groupBillboard,
         const.groupSentryGun,
         const.groupCapturePointTower,
         const.groupProtectiveSentryGun,
         const.groupCustomsOfficial]
        entitiesDict = {}
        nameDict = {}
        entityByGroup = {}
        for group in cfg.invgroups:
            if (group.categoryID in (const.categoryEntity)):
                if (group.groupID not in noLootEntities):
                    if (group.groupID not in dontSpawn):
                        entitiesDict[group.groupID] = []

        for type in cfg.invtypes:
            if (type.groupID in entitiesDict):
                entitiesDict[type.groupID].append(type.typeID)

        for id in entitiesDict.iterkeys():
            nameDict[id] = [cfg.invgroups.Get(id).name]

        for group in entitySpawnGroups:
            for (id, name,) in nameDict.iteritems():
                if name[0].lower().startswith(group.lower()):
                    if entityByGroup.has_key(group):
                        entityByGroup[group].append(id)
                        usedIDs.append(id)
                        allIDs.append(id)
                    else:
                        entityByGroup[group] = [id]
                        usedIDs.append(id)
                        allIDs.append(id)


        for id in nameDict.iterkeys():
            if (id not in usedIDs):
                if entityByGroup.has_key('Other'):
                    entityByGroup['Other'].append(id)
                    allIDs.append(id)
                else:
                    entityByGroup['Other'] = [id]
                    allIDs.append(id)

        for (displayName, idList,) in entityByGroup.iteritems():
            spawnMenu.append((displayName, lambda label = displayName, ids = idList: self.EntitySpawn(label, ids)))

        spawnMenu.sort()
        spawnMenu.append(None)
        spawnMenu.append(('No loot entities', lambda label = 'noloot', ids = noLootEntities: self.EntitySpawn(label, ids)))
        spawnMenu.append(None)
        spawnMenu.append(('<color=0xffff8080>All', lambda label = 'All', ids = allIDs: self.EntitySpawn(label, ids)))
        beltMenu = []
        constellationInRegion = sm.GetService('map').GetChildren(session.regionid)
        for constellationID in constellationInRegion:
            label = cfg.evelocations.Get(constellationID).name
            beltMenu.append((label, lambda ids = constellationID: self.RegionBeltTest(ids)))

        beltMenu.sort()
        beltMenu.append(None)
        beltMenu.append(('<color=0xffff8080>All', lambda ids = constellationInRegion: self.RegionBeltTest(ids)))
        gateMenu = []
        for constellationID in constellationInRegion:
            label = cfg.evelocations.Get(constellationID).name
            gateMenu.append((label, lambda ids = constellationID: self.RegionGateTest(ids)))

        gateMenu.sort()
        gateMenu.append(None)
        gateMenu.append(('<color=0xffff8080>All', lambda ids = constellationInRegion: self.RegionGateTest(ids)))
        (fw.append(('FW Bunker Locations', [('Amarr - Positive', lambda : self.RegionBunkerTest(True, 'Amarr')),
           ('Amarr - Negative', lambda : self.RegionBunkerTest(False, 'Amarr')),
           None,
           ('Caldari - Positive', lambda : self.RegionBunkerTest(True, 'Caldari')),
           ('Caldari - Negative', lambda : self.RegionBunkerTest(False, 'Caldari')),
           None,
           ('Gallente - Positive', lambda : self.RegionBunkerTest(True, 'Gallente')),
           ('Gallente - Negative', lambda : self.RegionBunkerTest(False, 'Gallente')),
           None,
           ('Minmatar - Positive', lambda : self.RegionBunkerTest(True, 'Minmatar')),
           ('Minmatar - Negative', lambda : self.RegionBunkerTest(False, 'Minmatar')),
           None,
           ('<color=0xffff8080>All - Positive', lambda : self.RegionBunkerTest(True, 'All')),
           ('<color=0xffff8080>All - Negative', lambda : self.RegionBunkerTest(False, 'All'))])))
        fw.append(None)
        fw.append(('NPC Loot Test', spawnMenu))
        fw.append(None)
        fw.append(('Belt Contents Survey', beltMenu))
        fw.append(('Gate Jump Test', gateMenu))
        fw.append(None)
        fw.append(('Client ReConnection Loop', lambda : sm.GetService('window').GetWindow('connectLoop', decoClass=form.ConnLoop, create=1)))
        fw.append(None)
        fw.append(('Stellar Objects Report', lambda : self.StoreRegionData()))
        fw.append(('FacWar Status Report', lambda : self.FacWarStatus()))
        fw.append(None)
        fw.append(('Spambot 2000', lambda : sm.GetService('cspam').Show()))
        return fw



    def ExpoMenu(self, *args):
        defaults = [(60005659,
          1,
          True,
          'Set as Team 1, Player 1'),
         (60005659,
          4,
          True,
          'Set as Team 1, Player 2'),
         (60005659,
          6,
          True,
          'Set as Team 1, Player 3'),
         None,
         (60005595,
          2,
          True,
          'Set as Team 2, Player 1'),
         (60005595,
          5,
          True,
          'Set as Team 2, Player 2'),
         (60005595,
          7,
          True,
          'Set as Team 2, Player 3'),
         None,
         (60005659,
          3,
          False,
          'Set as Administrator')]
        m = []
        n = []

        def ExpoPrefsSet(station, forcestation, setup):
            if forcestation:
                if util.IsStation(station):
                    prefs.SetValue('expoStartLocation', station)
                    prefs.SetValue('expoFittingID', setup)
                else:
                    eve.Message('CustomNotify', {'notify': ('The stationID %s is invalid.' % station)})
                    return 
            else:
                prefs.SetValue('expoStartLocation', station)
                prefs.SetValue('expoFittingID', setup)


        for entry in defaults:
            if (entry is None):
                n.append(None)
            else:
                (sID, eID, force, text,) = entry
                n.append((text,
                 ExpoPrefsSet,
                 (sID,
                  force,
                  eID)))

        m.append(('Setup characters', n))
        return m



    def OnSessionChanged(self, isRemote, sess, change):
        debugRenderJob = None
        for job in trinity.device.scheduledRecurring:
            if (job.name == 'DebugRender'):
                debugRenderJob = job
                break

        if debugRenderJob:
            trinity.device.scheduledRecurring.remove(debugRenderJob)



    def CreateDebugRenderer(self):
        job = getattr(self, 'DebugRenderJob', None)
        if not job:
            import GameWorld
            g = sm.GetService('gameWorldClient').GetGameWorld(session.worldspaceid)
            render_job = trinity.CreateRenderJob('DebugRender')
            callBackStep = trinity.TriStepPythonCB()
            callBackStep.SetCallback(g.PhysXRenderDebugInfo)
            render_job.steps.append(callBackStep)
            dr = trinity.TriStepRenderDebug()
            render_job.steps.append(dr)
            render_job.ScheduleRecurring()
            GameWorld.SetDebugRenderer(dr)
            setattr(self, 'DebugRenderJob', True)



    def AvatarMenu(self, *args):
        m = []

        def TogglePerceptionRendering():
            self.CreateDebugRenderer()
            pc = sm.GetService('perceptionClient')
            sceneID = session.worldspaceid
            pm = pc.GetPerceptionManager(sceneID)
            pm.ToggleDebugRendering()


        m.append(('Toggle Perception Rendering', TogglePerceptionRendering))

        def ToggleAimingRendering():
            pc = sm.GetService('aimingClient')
            sceneID = session.worldspaceid
            pm = pc.GetAimingManager(sceneID)
            pm.ToggleDebugRendering()


        m.append(('Toggle AI aiming Rendering', ToggleAimingRendering))

        def GazeNearest():
            pc = sm.GetService('aimingClient')
            sceneID = session.worldspaceid
            pm = pc.GetAimingManager(sceneID)
            pm.DebugGazeNearest()


        m.append(('Gaze at nearest entity', GazeNearest))

        def ChangeCameraZoom():
            sm.GetService('window').GetWindow('DebugChangeCameraSettingsWindow', decoClass=cameras.DebugChangeCameraSettingsWindow, create=1)


        m.append(('Change camera settings', ChangeCameraZoom))

        def ToogleProximityTreeRendering():
            self.CreateDebugRenderer()
            g = sm.GetService('gameWorldClient').GetGameWorld(session.worldspaceid)
            current = getattr(self, 'ProximityTreeCurrentlyRendering', False)
            if current:
                g.ProximityTreeDebugRendering = 0
                setattr(self, 'ProximityTreeCurrentlyRendering', False)
            else:
                g.ProximityTreeDebugRendering = 1
                setattr(self, 'ProximityTreeCurrentlyRendering', True)


        m.append(('Toogle Proximity Rendering', ToogleProximityTreeRendering))

        def ToggleDebugRenderClient():
            debugRender = sm.GetService('debugRenderClient')
            debugRender.SetDebugRendering((not debugRender.GetDebugRendering()))


        m.append(('Toggle debugRenderClient Rendering', ToggleDebugRenderClient))

        def ConnectToPhysXDebugger():
            gw = sm.GetService('gameWorldClient').GetGameWorld(session.worldspaceid)
            gw.ConnectToRemoteVisualDebugger('localhost', 5425)


        m.append(('Connect to PhysXDebugger', ConnectToPhysXDebugger))

        def ToggleAvatarRendering():
            sm.GetService('paperDollClient').ToogleRenderAvatars()


        m.append(('Toggle Avatar Rendering', ToggleAvatarRendering))

        def TeleportToSafeSpot():
            wsc = sm.GetService('worldSpaceClient')
            ec = sm.GetService('entityClient')
            safespot = wsc.GetWorldSpaceSafeSpot(session.worldspaceid)
            if ec.IsClientSideOnly(session.worldspaceid):
                ec.GetPlayerEntity().GetComponent('position').position = safespot[0]
            else:
                ret = sm.RemoteSvc('movementServer').RequestTeleport(safespot[0], safespot[1])
                if not ret:
                    eve.Message('CustomNotify', {'notify': 'Teleport failed'})


        m.append(('Teleport To Safesport', TeleportToSafeSpot))

        def OpenEntityBrowser():
            uicls.EntityBrowser(parent=uicore.layer.main)


        m.append(('Open Entity Browser', OpenEntityBrowser))

        def OpenZactionPanel():
            sm.GetService('window').GetWindow('ZactionPanel', create=1, maximize=1, decoClass=uicls.ZactionHackWindow)


        m.append(('Open Zaction Panel', OpenZactionPanel))

        def ToggleFlyMode():
            sm.GetService('movementClient').ToggleFlyMode()


        m.append(('Toggle Fly Mode', ToggleFlyMode))

        def IncrementTestCounter():
            server = sm.RemoteSvc('netStateServer')
            server.IncrementTestCounter()


        m.append(('Increment Test Counter', IncrementTestCounter))

        def ToggleCameraBoundMovement():
            sm.GetService('navigation').ToggleCameraBoundMovement()


        m.append(('Toggle Camera Bound Movement', ToggleCameraBoundMovement))

        def ToggleStickPhysXController():
            sm.GetService('movementClient').ToggleCharacterController()


        m.append(('Toggle Pogo', ToggleStickPhysXController))

        def ToggleExtrapolation():
            sm.GetService('movementClient').ToggleExtrapolation()


        m.append(('Toggle Extrapolation', ToggleExtrapolation))
        self.MakeMenu(m, 'Avatar_Btn')
        return m



    def QAMenu(self, *args):
        m = []
        (m.append(('Benchmarks', [('Connection Details', lambda : sm.StartService('window').GetWindow('bmdetails', create=1)),
           None,
           ('Station', lambda : benchmark1.Station()),
           ('Space', lambda : benchmark1.Space()),
           ('Autopilot', lambda : benchmark1.Autopilot()),
           ('NPC', lambda : benchmark1.NPC()),
           ('Map', lambda : benchmark1.Map()),
           None,
           ('<color=0xffff8080>All', lambda : benchmark1.All())])))
        m.append(None)
        m.append(('Automated Tasks', self.Automated()))
        self.MakeMenu(m, 'QA_Btn')



    def ImplantsMenu(self, *args):
        m = []
        implantsmenu = sm.GetService('implant').ImplantMenu()
        for entry in implantsmenu:
            try:
                m.append((entry[0], entry[1]))
            except:
                sys.exc_clear()
                m.append(None)

        self.MakeMenu(m, 'Implants_Btn')



    def DroneMenu(self, *args):
        m = []
        dronemenu = sm.GetService('charge').DroneMenu()
        for entry in dronemenu:
            try:
                m.append((entry[0], entry[1]))
            except:
                sys.exc_clear()
                m.append(None)

        self.MakeMenu(m, 'Drones_Btn')



    def ChargeMenu(self, *args):
        m = []
        chargemenu = sm.GetService('charge').ChargeMenu()
        for entry in chargemenu:
            try:
                if (entry.__class__ == dict):
                    m.append((entry['label'], None))
                    m.append(None)
                else:
                    m.append((entry[0], entry[1]))
            except:
                sys.exc_clear()
                m.append(None)

        self.MakeMenu(m, 'Charges_Btn')



    def ShipMenu(self, *args):
        shipmenu = sm.StartService('copycat').GetMenu_Ship()
        if (shipmenu is None):
            return 
        menu = []
        submenu = []
        for menuentry in shipmenu:
            if isinstance(menuentry, types.TupleType):
                if (len(menuentry) == 2):
                    (display, func,) = menuentry
                    if isinstance(func, types.TupleType):
                        subFunc = func[1]()
                        for entry in subFunc:
                            if isinstance(entry, types.TupleType):
                                submenu.append((entry[0], None))
                                submenu.append(None)
                            else:
                                if isinstance(entry, types.DictType):
                                    submenu.append((entry['label'],
                                     entry['action'],
                                     entry['args']))

                        if (len(submenu) == 0):
                            submenu = [('Nothing found', None)]
                        menu.append((display[0], submenu))
                        submenu = []
                    else:
                        menu.append((display[0], func))
                else:
                    if (len(menuentry) == 3):
                        (display, func, args,) = menuentry
                        menu.append((display[0],
                         func,
                         args))
            else:
                if isinstance(menuentry, types.NoneType):
                    menu.append(None)

        self.MakeMenu(menu, 'Ship_Btn')



    def MacroMenu(self, *args):
        m = []
        lines = sm.GetService('slash').GetMacros()
        lines.sort()
        for (macroName, comseq,) in lines:
            m.append((macroName, self.SlashBtnClick(comseq)))

        self.MakeMenu(m, 'Macro_Btn')



    def ToolMenu(self, *args):

        def CallMethod(*args):
            (objectName, callMethodOrNewWindow, isService,) = args
            if isService:
                return CallServiceMethod(*args)
            else:
                return CallFormMethod(*args)



        def CallServiceMethod(svcName, method, *args):
            return lambda : getattr(sm.GetService(svcName), method)()



        def CallFormMethod(formName, new, *args):
            return lambda : sm.StartService('window').GetWindow(formName, create=new)



        def GatherInsiderTools():
            import svc
            import form
            neocomGuid = '__neocommenuitem__'
            insiderObjects = []
            for (key, value,) in svc.__dict__.iteritems():
                isService = True
                if hasattr(value, neocomGuid):
                    insiderTool = getattr(value, neocomGuid)
                    insiderObjects.append((key,
                     insiderTool,
                     isService))

            for (key, value,) in form.__dict__.iteritems():
                isService = False
                if hasattr(value, neocomGuid):
                    insiderTool = getattr(value, neocomGuid)
                    insiderObjects.append((key,
                     insiderTool,
                     isService))

            return insiderObjects


        toolMenu = []
        insiderTools = GatherInsiderTools()
        for tool in insiderTools:
            try:
                (objectName, menuItem, isService,) = tool
                (windowInfo, callMethodOrNewWindow, requiredRole,) = menuItem
                (windowName, itemClassOrFormName,) = menuItem[0]
                if (((len(menuItem) >= 3) and (requiredRole & session.role)) or (len(menuItem) == 2)):
                    toolMenu.append((windowName, CallMethod(objectName, callMethodOrNewWindow, isService)))
            except (IndexError, ValueError):
                sys.exc_clear()
                continue

        toolMenu.sort()
        if (toolMenu[0][0] == '<color=0xffff8080>Python Console'):
            toolMenu.append(None)
            toolMenu.append(toolMenu.pop(0))
        toolMenu.append(None)
        action = ('gd/npc.py?action=BrowseSolarSystem&solarSystemID=' + str(session.solarsystemid2))
        toolMenu.append(('Solar system NPC info',
         sm.StartService('menu').GetFromESP,
         (action)))
        if trinity.IsFpsEnabled():
            toolMenu.append(('Turn FPS Monitor OFF',
             trinity.SetFpsEnabled,
             (False)))
        else:
            toolMenu.append(('Turn FPS Monitor ON',
             trinity.SetFpsEnabled,
             (True)))
        toolMenu.append(None)
        toolMenu += self.ExpoMenu()
        toolMenu.append(None)
        toolMenu.append(('Reload MLS',
         mls.Reload,
         ()))
        toolMenu.append(('Window Manager', lambda : sm.GetService('window').GetWindow('WindowManager', create=1)))
        toolMenu.append(('UI debugger', lambda : sm.GetService('window').GetWindow('UIDebugger', create=1)))
        self.MakeMenu(toolMenu, 'Tools_Btn')



    def Hide(self, *args):
        self.Show(show=False)



    def Reload(self):
        self.Hide()
        self.Show(force=True)
        eve.Message('CustomNotify', {'notify': 'Insider has been reloaded.'})



    def Show(self, show = True, force = False):
        if not (session.role & service.ROLEMASK_ELEVATEDPLAYER):
            return 
        if not force:
            if (session.role & service.ROLE_EXPOPLAYER):
                settings.public.ui.Set('Insider', False)
                show = False
        INSIDERDIR = self.GetInsiderDir()
        if not os.path.exists(INSIDERDIR):
            os.mkdir(INSIDERDIR)
        for each in uicore.layer.main.children:
            if (each.name in ('insider',)):
                each.Close()

        if (show == True):
            wnd = sm.GetService('window').GetWindow('insider', decoClass=form.InsiderWnd, create=1)
        else:
            wnd = sm.GetService('window').GetWindow('insider')
        settings.public.ui.Set('Insider', show)
        btn = []
        menus = [['Tools',
          self.ToolMenu,
          service.ROLEMASK_ELEVATEDPLAYER],
         ['Macro',
          self.MacroMenu,
          service.ROLE_GML],
         ['Ship',
          self.ShipMenu,
          service.ROLEMASK_ELEVATEDPLAYER],
         ['Charges',
          self.ChargeMenu,
          service.ROLE_GML],
         ['Drones',
          self.DroneMenu,
          service.ROLE_GML],
         ['Implants',
          self.ImplantsMenu,
          service.ROLE_GML],
         ['QA',
          self.QAMenu,
          service.ROLE_QA],
         ['Avatar',
          self.AvatarMenu,
          service.ROLE_QA]]
        for (label, func, role,) in menus:
            if (session.role & role):
                btn.append([label,
                 func,
                 None,
                 None])

        if wnd:
            btn = uix.MakeBtnGroup(btn, where=wnd.sr.main, line=0, uniSize=1)



    def Toggle(self, forceShow = False, *args):
        if settings.public.ui.Get('Insider', False):
            self.Hide()
        else:
            self.Show(force=forceShow)



    def WarpTo(self, itemID = None):
        if itemID:
            sm.GetService('slash').SlashCmd(('warpto %d' % itemID))


    exports = {'insider.Show': Show,
     'insider.Hide': Hide,
     'insider.Toggle': Toggle}


